<!-- Input with a delete icon when not empty. -->

<template>
  <div class="div-wrapper">
    <input
      class="in-entity"
      :placeholder="placeholder"
      type="text"
      v-model="inputText"
      @input="changeText(inputText)"
    />

    <i
      class="i-close-button fa-solid fa-circle-xmark"
      v-show="inputText.length > 0"
      @click="changeText('')"
    ></i>
  </div>
</template>

<script>
import { ref, watch } from "vue";

export default {
  props: {
    // How to enable a custom component to accept a v-model:
    // 1. Add a modelVaule prop from which we get the value of the external v-model variable.
    // 2. Wrap the modelValue prop in a new ref object and use it as our inner data.
    //    If modelValue is not a reference type object, i.e. if it is a String, we need to
    //    add a watch on the modelValue prop and manually make our inner data up-to-date.
    //    If modelValue is a reference type object, then we don't need to add a watch on it
    //    because changes of modelValue will be applied to our inner data automatically.
    //    However, if we directly assign to outer v-model variable, then a watch is still necessary.
    // 2. Add a call to emit when our inner data changes to make outer v-model variable updated.
    //    If outer v-model variable is an object or array, to watch its change we need to set
    //    deep to true. Maybe when vue handles the update event outside, it doesn't assign
    //    to the whole object or array but rather only does patches.
    modelValue: {
      type: String,
    },
    placeholder: {
      type: String,
      required: false,
      default: "",
    },
  },

  setup(props, { emit }) {
    // with this it is not enough to watch outer v-model variable changes.
    // we have to add an extra watch on modelValue to sync with outer value changes.
    // However, experiments show that if modelValue is a reference type,
    // then we do not need to add an extra watch. See single-disease for an example.
    const inputText = ref(props.modelValue);

    watch(
      () => props.modelValue,
      (newValue) => {
        inputText.value = newValue;
      }
    );

    function changeText(newText) {
      inputText.value = newText;
      emit("update:modelValue", inputText.value);
    }

    return {
      inputText,
      changeText,
    };
  },
};
</script>

<style scoped>
.div-wrapper {
  position: relative;

  display: inline-block;
}

.in-entity {
  width: 100%;
  padding: 10px;
  font-size: 14px;
  border: 0;
  border-top-left-radius: 0.25rem;
  border-bottom-left-radius: 0.25rem;
  outline: 0;
}

.i-close-button {
  color: #eee;
  cursor: pointer;
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  background-color: white;
}
</style>